/***********************************************************************************
 * 文件名： mcu_flash.c
 * 作者： 刘言
 * 版本： 1
 * 说明：
 * 		Flash 低层操作，提供整页擦写API。
 * 修改记录：
 * 	2024/9/6: 初版。 刘言。
***********************************************************************************/

#include "mcu_flash.h"

#if (defined PY32F002Bx5)
#define __HAL_FLASH_TIMMING_SEQUENCE_CONFIG()
#endif

IN_LINE static void Unlock()
{
    FLASH->KEYR = FLASH_KEY1;
    FLASH->KEYR = FLASH_KEY2;
}

// 给FLASH上锁，禁止擦写
IN_LINE static void Lock()
{
    SET_BIT(FLASH->CR, FLASH_CR_LOCK);
}


void Flash_WritePage(u32 addr, const u8 *buff)
{
    u16 i;
    u32 primask_bak;
    u32 dest = addr;
    const u32 * src = (const u32 *)buff;

    Unlock();

    __HAL_FLASH_TIMMING_SEQUENCE_CONFIG();

    while (READ_BIT(FLASH->SR, FLASH_SR_BSY) != 0);

    // 擦除页
    SET_BIT(FLASH->CR, FLASH_CR_PER);
    *(__IO uint32_t *)(addr) = 0xFF;
    while (READ_BIT(FLASH->SR, FLASH_SR_BSY) != 0);
    CLEAR_BIT(FLASH->CR, FLASH_CR_PER);

    // 写数据
    SET_BIT(FLASH->CR, FLASH_CR_PG);

    /* Enter critical section */
    primask_bak = __get_PRIMASK();
    __disable_irq();

    i = 0;
    while(i < FLASH_PAGE_SIZE / 4)
    {
        *(u32 *)dest = *src;
        src++;
        dest += 4;
        i++;
        if(i == 31)
        {
            SET_BIT(FLASH->CR, FLASH_CR_PGSTRT);
        }
    }
    
    /* Exit critical section: restore previous priority mask */
    __set_PRIMASK(primask_bak);

    while (READ_BIT(FLASH->SR, FLASH_SR_BSY) != 0);
    CLEAR_BIT(FLASH->CR, FLASH_CR_PG);

    Lock();
}






